/**
 * 算式类的单元测试
 * 测试AbstractCalculation抽象类及其子类AdditionCalculation和SubtractionCalculation
 */
public class CalculationTest {
    
    /**
     * 测试加法算式功能
     */
    public static void testAdditionCalculation() {
        // 测试基本加法
        AdditionCalculation add1 = new AdditionCalculation(5, 3);
        assert add1.getResult() == 8 : "加法计算错误: 5 + 3 应该等于 8";
        assert add1.checkAnswer(8) : "答案验证错误";
        assert !add1.checkAnswer(9) : "错误答案验证错误";
        
        // 测试表达式字符串生成
        assert add1.getExpression().equals("5 + 3") : "表达式字符串生成错误";
        assert add1.getFullExpression().equals("5 + 3 = 8") : "完整表达式字符串生成错误";
        
        // 测试边界情况：结果为100
        AdditionCalculation add2 = new AdditionCalculation(50, 50);
        assert add2.getResult() == 100 : "加法边界测试错误: 50 + 50 应该等于 100";
        
        // 测试加法工厂方法
        AdditionCalculation randomAdd = AdditionCalculation.createValidAddition();
        assert randomAdd.getResult() <= 100 : "随机加法结果超出范围";
        assert randomAdd.getOperator() == '+' : "运算符错误";
    }
    
    /**
     * 测试减法算式功能
     */
    public static void testSubtractionCalculation() {
        // 测试基本减法
        SubtractionCalculation sub1 = new SubtractionCalculation(8, 3);
        assert sub1.getResult() == 5 : "减法计算错误: 8 - 3 应该等于 5";
        assert sub1.checkAnswer(5) : "答案验证错误";
        assert !sub1.checkAnswer(4) : "错误答案验证错误";
        
        // 测试表达式字符串生成
        assert sub1.getExpression().equals("8 - 3") : "表达式字符串生成错误";
        assert sub1.getFullExpression().equals("8 - 3 = 5") : "完整表达式字符串生成错误";
        
        // 测试边界情况：结果为0
        SubtractionCalculation sub2 = new SubtractionCalculation(10, 10);
        assert sub2.getResult() == 0 : "减法边界测试错误: 10 - 10 应该等于 0";
        
        // 测试减法工厂方法
        SubtractionCalculation randomSub = SubtractionCalculation.createValidSubtraction();
        assert randomSub.getResult() >= 0 : "随机减法结果为负数";
        assert randomSub.getOperator() == '-' : "运算符错误";
    }
    
    /**
     * 测试抽象类方法和继承关系
     */
    public static void testAbstractCalculationMethods() {
        // 测试抽象类的通用方法
        AbstractCalculation add = new AdditionCalculation(10, 20);
        AbstractCalculation sub = new SubtractionCalculation(30, 15);
        
        // 测试继承的方法
        assert add.getOperand1() == 10 : "获取操作数错误";
        assert add.getOperand2() == 20 : "获取操作数错误";
        assert add.getOperator() == '+' : "获取运算符错误";
        
        assert sub.getOperand1() == 30 : "获取操作数错误";
        assert sub.getOperand2() == 15 : "获取操作数错误";
        assert sub.getOperator() == '-' : "获取运算符错误";
        
        // 测试toString方法
        assert add.toString().equals("10 + 20") : "toString方法错误";
        assert sub.toString().equals("30 - 15") : "toString方法错误";
    }
    
    /**
     * 测试异常情况
     */
    public static void testExceptions() {
        // 测试无效的加法（结果超过100）
        boolean addExceptionCaught = false;
        try {
            // 故意创建一个结果超过100的加法
            new AdditionCalculation(60, 50); // 60 + 50 = 110 > 100
        } catch (IllegalArgumentException e) {
            addExceptionCaught = true;
        }
        assert addExceptionCaught : "无效加法异常未抛出";
        
        // 测试无效的减法（结果为负数）
        boolean subExceptionCaught = false;
        try {
            // 故意创建一个结果为负数的减法
            new SubtractionCalculation(5, 10); // 5 - 10 = -5 < 0
        } catch (IllegalArgumentException e) {
            subExceptionCaught = true;
        }
        assert subExceptionCaught : "无效减法异常未抛出";
    }
    
    /**
     * 测试工厂方法的健壮性
     */
    public static void testFactoryMethodsRobustness() {
        // 多次调用工厂方法，确保生成的算式始终有效
        for (int i = 0; i < 100; i++) {
            // 测试加法工厂方法
            AdditionCalculation add = AdditionCalculation.createValidAddition();
            assert add.getResult() >= 0 && add.getResult() <= 100 : "随机加法结果无效";
            
            // 测试减法工厂方法
            SubtractionCalculation sub = SubtractionCalculation.createValidSubtraction();
            assert sub.getResult() >= 0 && sub.getResult() <= 100 : "随机减法结果无效";
            assert sub.getOperand1() >= sub.getOperand2() : "减法操作数顺序错误";
        }
    }
    
    /**
     * 主方法 - 运行所有测试
     */
    public static void main(String[] args) {
        System.out.println("开始算式类单元测试...");
        
        testAdditionCalculation();
        System.out.println("加法算式测试通过！");
        
        testSubtractionCalculation();
        System.out.println("减法算式测试通过！");
        
        testAbstractCalculationMethods();
        System.out.println("抽象类方法测试通过！");
        
        testExceptions();
        System.out.println("异常处理测试通过！");
        
        testFactoryMethodsRobustness();
        System.out.println("工厂方法健壮性测试通过！");
        
        System.out.println("所有测试通过！算式类功能正常。");
    }
}